﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.Net.Configuration;
using System.Net.Mail;

using TravelSite.DAL;
using TravelSite.DAL.Repositories;
using TravelSite.Entities;
using System.Net;
using System.Web.Security;
using OfficeOpenXml;
using System.Data;
using OfficeOpenXml.Style;

namespace TravelSite.Code
{
    public class Common
    {
        public static void EnumToDropDownList(Type enumType, bool includeAll, DropDownList ddl)
        {
            ddl.Items.Clear();

            var values = Enum.GetValues(enumType);
            if (includeAll)
                ddl.Items.Add(new ListItem("ALL", "ALL"));
            foreach (var itm in values)
            {
                ddl.Items.Add(new ListItem(Enum.GetName(enumType, itm), Enum.GetName(enumType, itm)));
            }
        }

        /*
        /// <summary>
        /// Send e-mail via smtp
        /// </summary>
        /// <param name="sendTo">Reciever</param>
        /// <param name="bcc">Reciever hide copy</param>
        /// <param name="subject">Subject</param>
        /// <param name="msgHtml">Message text in html</param>
        public static void SendEmail(string sendTo, string bcc, string subject, string msgHtml, bool sendAsHtml = true)
        {
            SmtpClient client = new SmtpClient();
            //client.EnableSsl = true;

            System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration("~/");
            SmtpSection smtpSection = (SmtpSection)config.GetSection("system.net/mailSettings/smtp");

            MailMessage msg = new MailMessage();
            msg.From = new MailAddress(smtpSection.Network.UserName);
            msg.To.Add(sendTo);
            if (bcc != "")
                msg.Bcc.Add(bcc);
            msg.Subject = subject;
            msg.IsBodyHtml = sendAsHtml;
            msg.Body = msgHtml;
            client.Send(msg);
        }
        */

        public static void SendEmail(string sendTo, string bcc, string subject, string msgHtml, bool sendAsHtml = true)
        {
            var user = Membership.GetUser();
            if (user == null) return;

            int? emailSettingId;
            using (var userRepo = RepositoryFactory.ResolveRepository<UserRepository>())
            {
                var findUser = userRepo.Find((Guid)user.ProviderUserKey);
                emailSettingId = findUser.EmailSettingId;
            }

            EmailSetting smtpConfig;
            using (var repo = RepositoryFactory.ResolveRepository<EmailSettingRepository>())
            {
                if (emailSettingId.HasValue)
                {
                    smtpConfig = repo.Find(emailSettingId.Value);
                }
                else
                {
                    smtpConfig = repo.Find();
                }
            }

            using (MailMessage mm = new MailMessage(smtpConfig.EmailFrom, sendTo))
            {
                if (bcc != "")
                    mm.Bcc.Add(bcc);

                mm.Subject = subject;
                mm.IsBodyHtml = sendAsHtml;
                mm.Body = msgHtml;

                using (SmtpClient sc = new SmtpClient(smtpConfig.ServerHost, smtpConfig.ServerPort))
                {
                    sc.EnableSsl = smtpConfig.UseSSL;
                    sc.UseDefaultCredentials = false;
                    sc.DeliveryMethod = SmtpDeliveryMethod.Network;
                    sc.Credentials = new NetworkCredential(smtpConfig.UserName, smtpConfig.Password);
                    sc.Send(mm);
                }
            }
        }

        public static void ContractToPdf(int contractId, Page page, bool agentTest, bool isDownload)
        {
            Contract cnt = null;
            List<ContractField> fields = null;
            using (var repo = RepositoryFactory.ResolveRepository<ContractRepository>())
            {
                cnt = repo.Find(contractId);
                if (cnt == null)
                {
                    ScriptManager.RegisterClientScriptBlock(page, page.GetType(), "Alert", "alert('Contract not found!');", true);
                    return;
                }

                fields = repo.ContractFields(null, contractId, null, null).ToList();
            }

            /*using (var repo = RepositoryFactory.ResolveRepository<ContactRepository>())
            {
                if (agentTest)
                {
                    if (!repo.IsMyContact(Convert.ToInt32((page as BasePage).CurrentUserId), cnt.ContactId))
                    {
                        ScriptManager.RegisterClientScriptBlock(page, page.GetType(), "Alert", "alert('You can't view this contract!');", true);
                        return;
                    }
                }
            }*/

            string fileName;
            using (var repo = RepositoryFactory.ResolveRepository<TemplateRepository>())
            {
                Template temp = repo.Find(cnt.TemplateId);
                fileName = temp.FileName;
            }

            string filePath = Path.Combine(page.Server.MapPath("~/Files/Templates"), fileName);
            if (!File.Exists(filePath))
            {
                ScriptManager.RegisterClientScriptBlock(page, page.GetType(), "Alert", "alert('Contract template file not found!');", true);
                return;
            }

            //MemoryStream ms = WordInterop.DocumentToPdf(WordInterop.DocumentFillFields(filePath, fields));

            ContractField fld;
            fld = new ContractField();
            fld.FieldName = "CardNumber";
            if ((!string.IsNullOrEmpty(cnt.CardNumber)) && (cnt.CardNumber.Length >= 4))
                fld.ContactColumnValue = cnt.CardNumber.Substring(cnt.CardNumber.Length - 4, 4);
            else
                fld.ContactColumnValue = cnt.CardNumber??"";
            fields.Add(fld);
            fld = new ContractField();
            fld.FieldName = "CardDate";
            fld.ContactColumnValue = cnt.CardDate??"";
            fields.Add(fld);
            fld = new ContractField();
            fld.FieldName = "CardCVV";
            fld.ContactColumnValue = cnt.CardCVV??"";
            fields.Add(fld);
            fld = new ContractField();
            fld.FieldName = "CardCC";
            fld.ContactColumnValue = cnt.CardCC??"";
            fields.Add(fld);
            
            MemoryStream ms = WordInterop.DocumentToPdf(WordInterop.DocumentFillPlaceHolders(filePath, fields));
            page.Response.Clear();
            /*if (isDownload)
            {
                page.Response.ContentType = "application/octet-stream";
                page.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName + ";");
            }
            else
                page.Response.ContentType = "application/pdf";*/

            page.Response.ContentType = "application/pdf";
            if (isDownload)
                page.Response.AddHeader("Content-Disposition", "attachment; filename=Contract.pdf;");

            page.Response.AddHeader("Accept-Header", ms.Length.ToString());
            page.Response.BinaryWrite(ms.ToArray());
            page.Response.End();
        }

        public static decimal StringToDecimal(string sValue)
        {
            decimal dOut;

            // try comma
            sValue = sValue.Replace(".", ",");
            if (Decimal.TryParse(sValue, out dOut))
                return dOut;
            else
            {
                // try dot
                sValue = sValue.Replace(",", ".");
                if (Decimal.TryParse(sValue, out dOut))
                    return dOut;
                else
                    throw new FormatException();
            }
        }

        public static ExcelPackage DataToExcel(List<object> data, List<string> headers, List<string> fields, List<string> format, string pageName)
        {
            ExcelPackage pck = new ExcelPackage();
            var ws = pck.Workbook.Worksheets.Add(pageName);

            int top = 1;
            int rowStartAutofit = 1;
            int left = 0;

            // Header
            for (int i = 0; i < headers.Count; ++i)
            {
                ++left;
                ws.Cells[top, left].Value = headers[i];
            }

            // Headers style
            var range = ws.Cells[top, 1, top, left];
            range.Style.Font.Bold = true;
            var border = range.Style.Border;
            border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thin;
            range.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;

            ++top;
            left = 1;

            // Data
            for (int i = 0; i < data.Count; ++i)
            {
                for (int j = 0; j < fields.Count; ++j)
                {
                    object value = GetPropValue(data[i], fields[j]);
                    if (value != null)
                        ws.Cells[top + i, left + j].Value = value;
                    ws.Cells[top + i, left + j].Style.Numberformat.Format = format[j];
                }
            }

            range = ws.Cells[top, left, top + data.Count - 1, left + fields.Count - 1];
            border = range.Style.Border;
            border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thin;

            top += data.Count - 1;
            ws.Cells[rowStartAutofit, left, top, left + fields.Count - 1].AutoFitColumns();

            return pck;
        }

        public static object GetPropValue(object src, string propName)
        {
            return src.GetType().GetProperty(propName).GetValue(src, null);
        }
    }
}